package com.kly.msg.serviceImpl;

import com.alibaba.fastjson.JSONObject;
import com.fqgj.common.api.Response;
import com.fqgj.exception.common.ApplicationException;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.Message;
import com.google.firebase.messaging.Notification;
import com.kly.dto.PushSendRequest;
import com.kly.enums.PushAPIEnum;
import com.kly.enums.SendStatusEnum;
import com.kly.msg.component.ApiClient;
import com.kly.msg.db.dao.TMessageDao;
import com.kly.msg.db.entity.TMessageEntity;
import com.kly.msg.dto.PushRequest;
import com.kly.service.PushMsgService;
import org.apache.commons.lang.StringUtils;
import org.aspectj.weaver.patterns.IToken;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.ExecutionException;

/**
 * push消息推送
 *
 * @author linqu
 */
@Service("pushMsgService")
public class PushMsgServiceImpl implements PushMsgService {

    private static Log LOGGER = LogFactory.getLog(PushMsgService.class);
    @Resource
    TMessageDao messageDao;
    @Resource
    ApiClient apiClient;

    @Override
    public Response<Boolean> singlePush(PushSendRequest pushSendRequest) {

        LOGGER.info("ReceiveMsg:{}", JSONObject.toJSONString(pushSendRequest));
        // 参数检查
        validatePushParameter(pushSendRequest);

        try {
            String response = null;
            if (PushAPIEnum.FCM.getId().equals(pushSendRequest.getPushProvider())) {
                response = pushMsgByFCM(pushSendRequest);
            } else if (PushAPIEnum.WEB_SOCKET.getId().equals(pushSendRequest.getPushProvider())) {
                pushMsgByWS(pushSendRequest);
            }

            //t_message 表不做存储
//            addMessage(pushSendRequest, response);
            return Response.ok();
        } catch (Exception e) {
            LOGGER.error("PushMsgError:{}, request:{}", JSONObject.toJSONString(pushSendRequest), e);
            return Response.error();
        }
    }

    private String pushMsgByWS(PushSendRequest pushSendRequest) throws Exception {

        final String content = pushSendRequest.getContent();
        final JSONObject contentJson = JSONObject.parseObject(content);

        JSONObject head = new JSONObject();
        head.put("token", contentJson.getString("token"));

        JSONObject requestParams = new JSONObject();
        requestParams.put("token", contentJson.getString("token"));
        requestParams.put("bizCode", contentJson.getString("bizCode"));
        requestParams.put("head", head.toJSONString());
        requestParams.put("body", content);

        return apiClient.post(requestParams).toJSONString();
    }

    private String pushMsgByFCM(PushSendRequest pushSendRequest) throws Exception {

        // 通知类消息，用于在任务栏中展示
        Message pushMsgContent = buildPushMsg(pushSendRequest);
        String response = FirebaseMessaging.getInstance().sendAsync(pushMsgContent).get();
        LOGGER.info("contentJson:{}, FirebaseMessagingResult:{}, ", pushSendRequest.getContent(), response);
        return response;
    }

    private void addMessage(PushSendRequest pushSendRequest, String response) {
        TMessageEntity message = new TMessageEntity();
        message.setAppCode(pushSendRequest.getApp());
        message.setRequestId(pushSendRequest.getRequestId());
        message.setContent(JSONObject.toJSONString(pushSendRequest));
        message.setProviderCode(pushSendRequest.getPushProvider());
        message.setStatus(SendStatusEnum.INIT.getCode());
        message.setFeedbackMsg(response);
        messageDao.insert(message);
    }

    public static void main(String[] args) {

    }

    private Message buildPushMsg(PushSendRequest pushSendRequest) {

        final String content = pushSendRequest.getContent();
        final JSONObject contentJson = JSONObject.parseObject(content);

        Notification notification = Notification.builder()
                .setTitle(contentJson.getString("title"))
                .setBody(contentJson.getString("body")).setImage(contentJson.getString("notificationImage")).build();
        Message message;
        if (com.fqgj.common.utils.StringUtils.isNotEmpty(contentJson.getString("imageUrl"))) {
            message = Message.builder()
                    .putData("type", contentJson.getString("type"))
                    .putData("isNotification", contentJson.getString("isNotification"))
                    .putData("targetId", contentJson.getString("targetId"))
                    .putData("imageUrl", contentJson.getString("imageUrl"))
                    .setToken(contentJson.getString("token"))
                    .setNotification(notification).build();
        } else {
            message = Message.builder()
                    .putData("type", contentJson.getString("type"))
                    .putData("isNotification", contentJson.getString("isNotification"))
                    .putData("targetId", contentJson.getString("targetId"))
                    .setToken(contentJson.getString("token"))
                    .setNotification(notification).build();
        }

        return message;
    }


    private void validatePushParameter(PushSendRequest pushSendRequest) {
        if (Objects.isNull(pushSendRequest)) {
            LOGGER.info("PushMsgService.singlePush parameter can not be null");
            throw new ApplicationException("Push request parameter validate failed");
        }
        if (Objects.isNull(pushSendRequest.getApp())) {
            LOGGER.info("PushMsgService.singlePush parameter [app] can not be null");
            throw new ApplicationException("Push request parameter [app] validate failed");
        }
        if (Objects.isNull(pushSendRequest.getPushProvider())) {
            LOGGER.info("PushMsgService.singlePush parameter [psuhAPI] can not be null");
            throw new ApplicationException("Push request parameter [psuhAPI] validate failed");
        }
        if (Objects.isNull(pushSendRequest.getContent())) {
            LOGGER.info("PushMsgService.singlePush parameter [content] can not be null");
            throw new ApplicationException("Push request parameter [content] validate failed");
        }
        if (StringUtils.isBlank(pushSendRequest.getRequestId())) {
            LOGGER.info("PushMsgService.singlePush parameter [requestId] can not be null");
            throw new ApplicationException("Push request parameter [requestId] validate failed");
        }
    }
}
